/*
 *
 */
package org.jiscinvolve.astrodabis.barberry.common.core;

import java.util.Date;
import java.util.Iterator;

import org.jiscinvolve.astrodabis.barberry.common.core.exception.*;

import org.jiscinvolve.astrodabis.barberry.common.data.RowTag;
import org.jiscinvolve.astrodabis.barberry.common.data.JoinTag;
import org.jiscinvolve.astrodabis.barberry.common.data.TapColumn;

/**
 *
 */
public interface Job
extends Identified, Tracked, Owned, Deletable
    {

    public interface Parser<T>
    extends Iterator<T>
        {
        public Job job();
        }

    public static enum AnnotType
        {
        JOINED(),
        SINGLE();
        }

    public static enum TagNameSrc
        {
        INPAGE(),
        INDATA();
        }

    public static enum TagDataSrc
        {
        INPAGE(),
        INDATA(),
        NONE();
        }

    public static enum SourceType
        {
        UPLOAD(),
        IMPORT(),
        QUERY();
        }

    public enum Status
        {
        EDITING(),
        PENDING(),        
        FETCHING(),        
        PROCESSING(),        
        COMPLETED(),        
        CANCELLED(),        
        FAILED()        
        }

    public interface Factory
        {

        public Identifier ident(String ident);

        public Job create(Account owner, Bean bean);
        public Job createQuick(Account owner, Bean bean);

        public Job select(Identifier ident);

        public Iterable<Job> select();

        public Iterable<Job> select(Account owner);

        public Iterable<Job> recent(int limit);
        public Iterable<Job> recent(Account owner, int limit);

        public Iterable<Job> rowtags(Tag tag);
        public Iterable<Job> jointags(Tag tag);

        //
        // Processing methods.
        public long batch(Job job, long limit, Iterator iter)
        throws ProcessingException;

        //
        // Update methods.
        public void push(Job job);
        public void pushQuick(Job job);

        public void update(Job job);
        public void delete(Job job);

        }

    public String name();
    public String text();

    public AnnotType annotType();

    public TapColumn columnOne();
    public TapColumn columnTwo();

    public String colNameOne(); 
    public String colNameTwo(); 

    public TagNameSrc tagNameSrc();
    public TagDataSrc tagDataSrc();

    public String tagName();
    public Double tagData();

    public SourceType sourceType();
    public String sourceUrl();

    public Status status();
    public void status(Status status);

    public long count();
    public void count(long count);

    public Date started();
    public Date finished();

    public void update(Bean bean);
    public void fail(Throwable cause);

    public interface Tags
        {
        public Iterable<Tag> select();
        }

    public Tags tags();

    public interface RowTags
        {
        public Iterable<RowTag> select();
        public Iterable<RowTag> select(int limit);
        }

    public RowTags rowtags();

    public interface JoinTags
        {
        public Iterable<JoinTag> select();
        public Iterable<JoinTag> select(int limit);
        }

    public JoinTags jointags();


    //
    // This should not be here ..
    public static class Bean
        {

        public Bean()
            {
            }

        public Bean(
            String name,
            String text,
            TapColumn columnOne
            ){
            this(
                name,
                text,
                AnnotType.SINGLE,
                columnOne,
                null,
                null,
                null,
                TagNameSrc.INDATA,
                TagDataSrc.NONE,
                null,
                null,
                null,
                null
                );
            }

        public Bean(
            String name,
            String text,
            TapColumn columnOne,
            String colNameOne
            ){
            this(
                name,
                text,
                AnnotType.SINGLE,
                columnOne,
                null,
                colNameOne,
                null,
                TagNameSrc.INDATA,
                TagDataSrc.NONE,
                null,
                null,
                null,
                null
                );
            }

        public Bean(
            String name,
            String text,
            TapColumn columnOne,
            TapColumn columnTwo
            ){
            this(
                name,
                text,
                AnnotType.JOINED,
                columnOne,
                columnTwo,
                null,
                null,
                TagNameSrc.INDATA,
                TagDataSrc.NONE,
                null,
                null,
                null,
                null
                );
            }

        public Bean(
            String name,
            String text,
            TapColumn columnOne,
            TapColumn columnTwo,
            String colNameOne,
            String colNameTwo
            ){
            this(
                name,
                text,
                AnnotType.JOINED,
                columnOne,
                columnTwo,
                colNameOne,
                colNameTwo,
                TagNameSrc.INDATA,
                TagDataSrc.NONE,
                null,
                null,
                null,
                null
                );
            }

        public Bean(
            String name,
            String text,
            AnnotType annotType,
            TapColumn columnOne,
            TapColumn columnTwo,
            String colNameOne,
            String colNameTwo,
            TagNameSrc tagNameSrc,
            TagDataSrc tagDataSrc,
            String tagName,
            Double tagData,
            SourceType sourceType,
            String sourceUrl
            ){
            this.name = name ;
            this.text = text ;
            this.annotType = annotType ;
            this.columnOne = columnOne ;
            this.columnTwo = columnTwo ;
            this.colNameOne = colNameOne ;
            this.colNameTwo = colNameTwo ;
            this.tagNameSrc = tagNameSrc ;
            this.tagDataSrc = tagDataSrc ;
            this.tagName = tagName ;
            this.tagData = tagData ;
            this.sourceType = sourceType ;
            this.sourceUrl  = sourceUrl ;
            }

        public Bean(Job job)
            {

            this.name = job.name() ;
            this.text = job.text() ;

            this.annotType = job.annotType() ;

            this.columnOne = job.columnOne() ;
            this.columnTwo = job.columnTwo() ;

            this.colNameOne = job.colNameOne() ;
            this.colNameTwo = job.colNameTwo() ;

            this.tagNameSrc = job.tagNameSrc() ;
            this.tagDataSrc = job.tagDataSrc() ;
            this.tagName = job.tagName() ;
            this.tagData = job.tagData() ;
            this.sourceType = job.sourceType() ;
            this.sourceUrl  = job.sourceUrl() ;

            }

        protected String name;
        public String getName()
            {
            return this.name ;
            }
        public void setName(String name)
            {
            this.name = name ;
            }

        protected String text;
        public String getText()
            {
            return this.text ;
            }
        public void setText(String text)
            {
            this.text = text ;
            }

        protected AnnotType annotType;
        public AnnotType getAnnotType()
            {
            return this.annotType ;
            }
        public void setAnnotType(AnnotType value)
            {
            this.annotType = value ;
            }

        protected TapColumn columnOne;
        public TapColumn getColumnOne()
            {
            return this.columnOne ;
            }

        protected TapColumn columnTwo;
        public TapColumn getColumnTwo()
            {
            return this.columnTwo ;
            }

        protected String colNameOne;
        public String getColNameOne()
            {
            return this.colNameOne ;
            }

        protected String colNameTwo;
        public String getColNameTwo()
            {
            return this.colNameTwo ;
            }

        private TagNameSrc tagNameSrc = TagNameSrc.INPAGE ;
        public TagNameSrc getTagNameSrc()
            {
            return this.tagNameSrc ;
            }
        public void setTagNameSrc(TagNameSrc value)
            {
            this.tagNameSrc = value ;
            }

        private TagDataSrc tagDataSrc = TagDataSrc.NONE ;
        public TagDataSrc getTagDataSrc()
            {
            return this.tagDataSrc ;
            }
        public void setTagDataSrc(TagDataSrc value)
            {
            this.tagDataSrc = value ;
            }

        protected String tagName;
        public String getTagName()
            {
            return this.tagName ;
            }
        public void setTagName(String value)
            {
            this.tagName = value ;
            }

        protected Double tagData;
        public Double getTagData()
            {
            return this.tagData ;
            }
        public void setTagData(Double value)
            {
            this.tagData = value ;
            }

        protected SourceType sourceType = SourceType.UPLOAD ;
        public SourceType getSourceType()
            {
            return this.sourceType ;
            }
        public void setSourceType(SourceType value)
            {
            this.sourceType = value ;
            }

        protected String sourceUrl;
        public String getSourceUrl()
            {
            return this.sourceUrl ;
            }
        public void setSourceUrl(String value)
            {
            this.sourceUrl = value ;
            }
        }
    }

